import uuid

from user.models import Viptype, Vip
from app01.libs.ipay import GATEWAY, alipay
from rest_framework import serializers
from .models import Order, OrderDetail
from rest_framework.exceptions import APIException
from django.conf import settings


class OrderSerializer(serializers.ModelSerializer):
    viptypes = serializers.PrimaryKeyRelatedField(queryset=Viptype.objects.all(), write_only=True, many=True)

    class Meta:
        model = Order
        fields = ['viptypes', 'total_amount', 'pay_type', 'subject']
        extra_kwargs = {
            'total_amount': {
                'required': True,
                'write_only': True
            },
            'pay_type': {
                'required': True,
                'write_only': True
            },
            'subject': {
                'required': True,
                'write_only': True
            },
        }

    def _check_total_amount(self, attrs):
        total_amount = float(attrs.get('total_amount'))
        course_list = attrs.get('viptypes')
        new_total_amount = 0
        for course in course_list:
            new_total_amount += course.price
        if not new_total_amount == total_amount:
            raise APIException(detail='价格不合法')
        return total_amount

    def _get_out_trade_no(self):
        return str(uuid.uuid4())

    def _get_user(self):
        return self.context.get('request').user

    def _get_pay_url(self, out_trade_no, total_amount, subject):
        res = alipay.api_alipay_trade_page_pay(
            out_trade_no=out_trade_no,
            total_amount=float(total_amount),  # 只有生成支付宝链接时，不能用Decimal
            subject=subject,
            return_url=settings.RETURN_URL,
            notify_url=settings.NOTIFY_URL,
        )
        pay_url = GATEWAY + res
        self.context['pay_url'] = pay_url

    def _before_create(self, attrs, user, out_trade_no):
        attrs['user'] = user
        attrs['out_trade_no'] = out_trade_no

    def validate(self, attrs):
        # 1）订单总价校验
        total_amount = self._check_total_amount(attrs)
        # 2）生成订单号
        out_trade_no = self._get_out_trade_no()
        # 3）支付用户：request.user
        user = self._get_user()
        import datetime
        print(datetime.datetime.now())
        from dateutil.relativedelta import relativedelta
        course_list = attrs.get('viptypes')
        # print(course_list[0])
        res = Vip.objects.filter(user=user).first()
        from redis import Redis

        conn = Redis(host="localhost", port=6379, )
        if res:
            expiration_time = res.expiration_time
            expiration_time += relativedelta(days=(course_list[0].id*30))
            conn.lpush('gg', '感谢用户%s续费会员' % user.username)
            conn.close()
        else:
            expiration_time = datetime.datetime.now() + relativedelta(months=course_list[0].id)
            conn.lpush('gg', '恭喜用户%s成为本站的会员' % user.username)
            conn.close()
        Vip.objects.update_or_create(defaults={"expiration_time": expiration_time}, user=user)
        # 4）支付链接生成
        self._get_pay_url(out_trade_no, total_amount, attrs.get('subject'))
        # 5）入库(两个表)的信息准备
        self._before_create(attrs, user, out_trade_no)

        return attrs

    def create(self, validated_data):
        course_list = validated_data.pop('viptypes')
        order = Order.objects.create(**validated_data)
        for course in course_list:
            OrderDetail.objects.create(order=order, Vip=course, price=course.price, real_price=course.price)
        return order
